import electron, { remote } from 'electron';
import path from 'path';
import fs from 'fs';
import { spawn } from 'child_process';
import cfg from './config';
import * as util from '../util';
import { checkVersion, download } from './download';
import { send } from './help';

const onEvent = (...args) => send('hotUpdate', ...args);
const app = electron.app || remote.app;
const resourcesDir = path.join(cfg.dirs.appPath, 'resources');
const filename = 'app.asar';
const asarPath = path.join(resourcesDir, filename);
const loger = util.loger;
let isBusying;
const name = 'hot';

/**
 * 检查版本
 */

const hotCheck = ({ urlDownload = cfg.urlDownload, ...args } = {}) => {
  return checkVersion({ name, oldVersion: cfg.version, urlDownload, ...args });
};

const cfgSave = () => {
  isBusying = false;
  cfg.hotLastCheck = new Date();
  cfg.save();
};

/**
 * 获取程序
 */

const hotUpdate = ({ urlDownload = cfg.urlDownload, ...args } = {}) => {
  if (isBusying) {
    return Promise.reject({ isBusying });
  }
  isBusying = true;
  onEvent('checking');
  return hotCheck({ isSemver: true, urlDownload, ...args })
    .then(data => {
      loger.debug('hotUpdate', 'checkVersion', data);
      if (!data || !data.hasUpdate || !data.files || !data.files[filename]) {
        onEvent('not-available');
        return;
      }
      onEvent('available');
      const downArgs = {
        fileUrl: `${urlDownload}${name}/${data.version}/${filename}`,
        filePath: asarPath,
        fileMd5: data.files[filename],
        threads: 3,
        ...args,
        onEvent: (type, res) => {
          switch (type) {
            case 'error':
              onEvent('error', res);
              break;
            case 'progress':
              onEvent('progress', res);
              break;
          }
        },
      };
      return download(downArgs).then(res => {
        const { filePath, fileSave } = res;
        const updateExe = path.join(cfg.dirs.appPath, 'update.exe');
        const updaterJsonFile = path.join(cfg.dirs.appData, 'update.json');
        const updaterJson = JSON.stringify({
          files: {
            [fileSave]: filePath,
          },
          command: app.getPath('exe'),
        });
        onEvent('download');
        fs.writeFileSync(updaterJsonFile, updaterJson);
        onEvent('before-quit');
        cfgSave();
        spawn(updateExe, [updaterJsonFile], {
          detached: true,
          windowsVerbatimArguments: true,
          stdio: 'ignore',
        });
        app.quit();
      });
    })
    .then(() => {
      cfgSave();
    })
    .catch(error => {
      cfgSave();
      throw error;
    });
};

export default {
  hotCheck,
  hotUpdate,
};
